home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / Xconq 7.1.0 / src / xconq-7.1.0 / x11 / xutil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-07  |  12.9 KB  |  628 lines  |  [TEXT/R*ch]

  1. /* Utilities needed for X11 utility programs.
  2.    Copyright (C) 1993, 1994, 1995, 1996 Stanley T. Shebs.
  3.  
  4. Xconq is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.  See the file COPYING.  */
  8.  
  9. #include "config.h"
  10. #include "misc.h"
  11. #include "lisp.h"
  12. #include "imf.h"
  13. #include "xutil.h"
  14. #include "ximf.h"
  15.  
  16. #include <X11/Xos.h>
  17. #include <X11/Xlib.h>
  18. #include <X11/Xutil.h>
  19. #include <X11/Xresource.h>
  20. #include <X11/Xmu/Drawing.h>
  21.  
  22. #ifdef HAVE_XPM
  23. #include <X11/xpm.h>
  24. #endif
  25.  
  26. extern int numimages;
  27. char *outdirname = NULL;
  28. char *imflib = "";
  29.  
  30. LibraryPath *xconq_libs;
  31.  
  32. /* this is needed to resolve
  33.    extern char spbuf[];
  34.    declared in kernel/unix.c */
  35. char spbuf[BUFSIZE];
  36.  
  37. void
  38. close_displays()
  39. {
  40. }
  41.  
  42. int
  43. write_entire_game_state(fname)
  44. char *fname;
  45. {
  46.     return 0;
  47. }
  48.  
  49. /* Need these so we can link in Lisp reader code. */
  50.  
  51. void
  52. announce_read_progress()
  53. {
  54. }
  55.  
  56. void
  57. low_init_error(str)
  58. char *str;
  59. {
  60.     fprintf(stderr, "Error: %s.\n", str);
  61.     fflush(stderr);
  62. }
  63.  
  64. /* A warning just gets displayed, no other action is taken. */
  65.  
  66. void
  67. low_init_warning(str)
  68. char *str;
  69. {
  70.     fprintf(stdout, "Warning: %s.\n", str);
  71.     fflush(stdout);
  72. }
  73.  
  74. /* A run error is fatal. */
  75.  
  76. void
  77. low_run_error(str)
  78. char *str;
  79. {
  80.     fprintf(stderr, "Error: %s.\n", str);
  81.     fflush(stderr);
  82.     exit(1);
  83. }
  84.  
  85. /* Runtime warnings are for when it's important to bug the players,
  86.    usually a problem with Xconq or a game design. */
  87.  
  88. void
  89. low_run_warning(str)
  90. char *str;
  91. {
  92.     fprintf(stdout, "Warning: %s.\n", str);
  93.     fflush(stdout);
  94. }
  95.  
  96. /* Fake definitions of unneeded routines called by lisp.c. */
  97.  
  98. int
  99. keyword_code(str)
  100. char *str;
  101. {
  102.     run_warning("fake keyword_code being called");
  103.     return 0;
  104. }
  105.  
  106. /* Make the table so keyword lookup works. */
  107.  
  108. struct a_key {
  109.     char *name;
  110. } keywordtable[] = {
  111.  
  112. #undef  DEF_KWD
  113. #define DEF_KWD(NAME,code)  { NAME },
  114.  
  115. #include "keyword.def"
  116.  
  117.     { NULL }
  118. };
  119.  
  120. char *
  121. keyword_name(k)
  122. enum keywords k;
  123. {
  124.     return keywordtable[k].name;
  125. }
  126.  
  127. void
  128. init_predefined_symbols()
  129. {
  130. }
  131.  
  132. int
  133. lazy_bind(sym)
  134. Obj *sym;
  135. {
  136.     run_warning("fake lazy_bind being called");
  137.     return FALSE;
  138. }
  139.  
  140. void
  141. prealloc_debug()
  142. {
  143. }
  144.  
  145. /* read/write images in X format. */
  146.  
  147. Image *
  148. read_xbm_file(filename, imf, hook)
  149. char *filename;
  150. ImageFamily *imf;
  151. readimf_hook hook;
  152. {
  153.     FILE *ifp;
  154.     int rows, cols, rowbytes;
  155.     unsigned int urows, ucols;
  156.     unsigned char *urawdata;
  157.     char *rawdata;
  158.     Image *img;
  159.  
  160.     if (!imf)
  161.       return NULL;
  162.     if (!(ifp = fopen(filename, "r")))
  163.       return NULL;
  164.  
  165.     if (XmuReadBitmapData(ifp, &ucols, &urows, &urawdata, NULL, NULL)
  166.     != BitmapSuccess)
  167.       return NULL;
  168.     cols = ucols;
  169.     rows = urows;
  170.     rawdata = (char *) urawdata;
  171.     fclose(ifp);
  172.     img = get_img(imf, cols, rows);
  173.     if (!img)
  174.       return NULL;
  175.     if (hook) {
  176.     /* force image re-generation */
  177.     img->monodata = img->colrdata = img->maskdata = lispnil;
  178.     }
  179.     rowbytes = (cols + 7) / 8;
  180.     if (filename[strlen(filename)-1] == 'm') {
  181.     img->rawmaskdata = xmalloc(rows * rowbytes);
  182.     memcpy(img->rawmaskdata, rawdata, rows * rowbytes);
  183.     } else {
  184.     img->rawmonodata = xmalloc(rows * rowbytes);
  185.     memcpy(img->rawmonodata, rawdata, rows * rowbytes);
  186.     }
  187.     return img;
  188. }
  189.  
  190. Image *
  191. read_xpm_file(filename, imf, hook)
  192. char *filename;
  193. ImageFamily *imf;
  194. readimf_hook hook;
  195. {
  196. #ifdef HAVE_XPM
  197.     int c, numbytes, *dp, r, ri, cols, rows;
  198.     char *rp, rmask;
  199.     XpmImage xpmimage;
  200.     XpmInfo info;
  201.     Image *img;
  202.  
  203.     if (!imf)
  204.       return NULL;
  205.     if (XpmReadFileToXpmImage(filename, &xpmimage, &info) != XpmSuccess) {
  206.     return NULL;
  207.     }
  208.     cols = xpmimage.width;
  209.     rows = xpmimage.height;
  210.     img = get_img(imf, cols, rows);
  211.     if (!img)  return NULL;
  212.     if (hook) {
  213.     /* force image re-generation */
  214.     img->monodata = img->colrdata = img->maskdata = lispnil;
  215.     }
  216.     img->actualw = cols;
  217.     img->actualh = rows;
  218.     img->numcolors = xpmimage.ncolors;
  219.     if (xpmimage.ncolors>256) {
  220.     low_run_warning("Image with more then 256 colors not supported\n");
  221.     return NULL;
  222.     } else if (xpmimage.ncolors>16) {
  223.     img->pixelsize = 8;
  224.     } else if (xpmimage.ncolors>4) {
  225.     img->pixelsize = 4;
  226.     } else if (xpmimage.ncolors>2) {
  227.     img->pixelsize = 2;
  228.     } else {
  229.     img->pixelsize = 1;
  230.     }
  231.     img->rowbytes = (img->w*img->pixelsize + 7) / 8;
  232.     img->rawpalette = (int *) xmalloc(img->numcolors*4*sizeof(int));
  233.     for (c=0; c<img->numcolors; c++) {
  234.     img->rawpalette[4*c] = c;
  235.     parse_xpm_colors(xpmimage.colorTable[c].c_color,
  236.              &img->rawpalette[4*c+1],
  237.              &img->rawpalette[4*c+2],
  238.              &img->rawpalette[4*c+3]);
  239.     }
  240.     /* this seems to be Stan's default ;-) */
  241.     img->rawpalette[4*(img->numcolors-1)] = (1<<img->pixelsize)-1;
  242.     numbytes = img->h * img->rowbytes;
  243.     img->rawcolrdata = xmalloc(numbytes);
  244.     memset(img->rawcolrdata, '\0', numbytes);
  245.     rp = img->rawcolrdata;
  246.     dp = (int *) xpmimage.data;
  247.     rmask = (1<<img->pixelsize) - 1;
  248.     for (r=0; r<img->h; r++) {
  249.     ri = 8 - img->pixelsize;
  250.     for (c=0; c<img->w; c++) {
  251.         *rp |= (img->rawpalette[4*(*dp)] & rmask)<<ri;
  252.         dp++;
  253.         if (ri) {
  254.         ri -= img->pixelsize;
  255.         } else {
  256.         ri = 8 - img->pixelsize;
  257.         rp++;
  258.         }
  259.     }
  260.     if ((img->pixelsize*img->w)%8) {
  261.         rp++;
  262.     }
  263.     }
  264.  
  265.     return img;
  266. #else
  267.     return NULL;
  268. #endif
  269. }
  270.  
  271. /* half-witted replacement for XParseColor, which we can't use
  272.    since we could have no display open */
  273. void
  274. parse_xpm_colors(name, r, g, b)
  275. char *name;
  276. int *r;
  277. int *g; 
  278. int *b; 
  279. {
  280.     int n, q;
  281.     char xpmcbuf[32];
  282.  
  283.     /* sometimes "pixmap" comes up with these: */
  284.     if (!strcmp(name,"white") || !strcmp(name,"White")) {
  285.     *r = *g = *b = 0xffff;
  286.     return;
  287.     }
  288.     if (!strcmp(name,"black") || !strcmp(name,"Black")) {
  289.     *r = *g = *b = 0;
  290.     return;
  291.     }
  292.  
  293.  
  294.     if (name[0]!='#') {
  295.     fprintf(stderr, "Error parsing color %s\n", name);
  296.     return;
  297.     }
  298.     name++;
  299.     n = strlen(name);
  300.     if (n%3) {
  301.     fprintf(stderr, "Error parsing color %s\n", name);
  302.     return;
  303.     }
  304.     n /= 3;
  305.     sprintf(xpmcbuf, "%%%dx%%%dx%%%dx", n, n, n);
  306.     q = sscanf(name, xpmcbuf, r, g, b);
  307.     if (q!=3) {
  308.     fprintf(stderr, "Error parsing color %s\n", name);
  309.     return;
  310.     }
  311.     if (n<4) {
  312.     *r <<= 4*(4-n);
  313.     *g <<= 4*(4-n);
  314.     *b <<= 4*(4-n);
  315.     }
  316. }
  317.  
  318. void
  319. write_x11_bitmaps(imf, mkfiles)
  320. ImageFamily *imf;
  321. int mkfiles;
  322. {
  323.     int w, h, rowbytes, numbytes;
  324.     char ext[20], fname[255];
  325.     FILE *fp;
  326.     Image *img;
  327.  
  328.     if (imf == NULL || imf->name == NULL) return;
  329.     for (img = imf->images; img != NULL; img = img->next) {
  330.     w = img->w;  h = img->h;
  331.     /* unified size marker in extension.  Massimo */
  332.     sprintf(ext, ".%dx%d", w, h);
  333.     if (img->monodata != lispnil && img->rawmonodata == NULL) {
  334.         rowbytes = (w + 7) / 8;
  335.         numbytes = h * rowbytes;
  336.         img->rawmonodata = xmalloc(numbytes);
  337.         interp_bytes(img->monodata, numbytes, img->rawmonodata, 0);
  338.         reverse_bit_endianness(img->rawmonodata, numbytes);
  339.     }
  340.     if (img->rawmonodata) {
  341.         if (mkfiles) {
  342.         sprintf(fname, "%s/%s%s.b", outdirname, imf->name, ext);
  343.         fp = fopen(fname, "w");
  344.         } else {
  345.         fp = stdout;
  346.         }
  347.         if (fp != NULL) {
  348.         write_xbm_file(fp, imf->name, w, h, img->rawmonodata);
  349.         if (fp != stdout)
  350.           fclose(fp);
  351.         }
  352.     }
  353.     if (img->maskdata != lispnil && img->rawmaskdata == NULL) {
  354.         rowbytes = (w + 7) / 8;
  355.         numbytes = h * rowbytes;
  356.         img->rawmaskdata = xmalloc(numbytes);
  357.         interp_bytes(img->maskdata, numbytes, img->rawmaskdata, 0);
  358.         reverse_bit_endianness(img->rawmaskdata, numbytes);
  359.     }
  360.     if (img->rawmaskdata) {
  361.         if (mkfiles) {
  362.         sprintf(fname, "%s/%s%s.m", outdirname, imf->name, ext);
  363.         fp = fopen(fname, "w");
  364.         } else {
  365.         fp = stdout;
  366.         }
  367.         if (fp != NULL) {
  368.         write_xbm_file(fp, imf->name, w, h, img->rawmaskdata);
  369.         if (fp != stdout)
  370.           fclose(fp);
  371.         }
  372.     }
  373.     if (img->colrdata != lispnil && img->rawcolrdata == NULL) {
  374.         rowbytes = (w * img->pixelsize + 7) / 8;
  375.         numbytes = h * rowbytes;
  376.         img->rawcolrdata = xmalloc(numbytes);
  377.         interp_bytes(img->colrdata, numbytes, img->rawcolrdata, 0);
  378.     }
  379.     if (img->rawcolrdata) {
  380.         if (mkfiles) {
  381.         sprintf(fname, "%s/%s%s.xpm", outdirname, imf->name, ext);
  382.         fp = fopen(fname, "w");
  383.         } else {
  384.         fp = stdout;
  385.         }
  386.         if (fp != NULL) {
  387.         write_xpm_file(fp, imf->name, img);
  388.         if (fp != stdout)
  389.           fclose(fp);
  390.         }
  391.     }
  392.     }
  393. }
  394.  
  395. /* Write a bitmap in more-or-less standard X11 format. */
  396.  
  397. void
  398. write_xbm_file(fp, name, cols, rows, data)
  399. FILE *fp;
  400. char *name;
  401. int cols, rows;
  402. char *data;
  403. {
  404.     int row, i = 0, col;
  405.     int bytesperline = 8;
  406.     int byte, byte2, j, firstitem = 1;
  407.     int numbytes = ((cols + 7) / 8) * rows;
  408.  
  409.     reverse_bit_endianness(data, numbytes);
  410.  
  411.     fprintf(fp, "#define %s_width %d\n", name, cols);
  412.     fprintf(fp, "#define %s_height %d\n", name, rows);
  413.     fprintf(fp, "static char %s_bits[] = {", name);
  414.     for (row = 0; row < rows; row++) {
  415.     for (col = 0; col < cols; col++) {
  416.         if (col % 8 == 0) {
  417.         if (firstitem) {
  418.             firstitem = 0;
  419.         } else {
  420.             putc(',', fp);
  421.             putc(' ', fp);
  422.         }
  423.         if (bytesperline >= 8) {
  424.             fprintf(fp, "\n   ");
  425.             bytesperline = 0;
  426.         }
  427.         /* Make little-endian bytes. */
  428.         byte = data[i++];
  429.         byte2 = 0;
  430.         for (j = 0; j < 8; ++j) {
  431.             byte2 = (byte2 << 1) | (byte & 1);
  432.             byte >>= 1;
  433.         }
  434.         fprintf(fp, "0x%x", byte2);
  435.         ++bytesperline;
  436.         }
  437.     }
  438.     }
  439.     fprintf(fp, "};\n" );
  440.  
  441.     reverse_bit_endianness(data, numbytes);
  442. }
  443.  
  444. void
  445. write_xpm_file(fp, name, img)
  446. FILE *fp;
  447. char *name;
  448. Image *img;
  449. {
  450.     int r, ri, rc, c, numcols, rmask;
  451.     char pch[256], *rp;
  452.     int idx[256];
  453.     Obj *palette, *color;
  454.  
  455.     if (img->palette==lispnil && !(img->rawpalette && img->numcolors))
  456.       return;
  457.  
  458.     if (img->palette==lispnil) {
  459.     numcols = img->numcolors;
  460.     } else {
  461.     c = 0;
  462.     for (palette=img->palette; palette != lispnil; palette = cdr(palette)) {
  463.         c++;
  464.     }
  465.     numcols = c;
  466.     }
  467.  
  468.     fprintf(fp, "/* XPM */\n");
  469.     fprintf(fp, "static char * %s [] = {\n", name);
  470.     fprintf(fp, "\"%d %d %d %d\",\n", img->w, img->h, numcols, 1);
  471.  
  472.     for (c=0; c<numcols; c++) {
  473.     if (c<26) {
  474.         pch[c] = 'a' + c;
  475.     } else if (c<52) {
  476.         pch[c] = 'A' + c-26;
  477.     } else if (c<62) {
  478.         pch[c] = '0' + c-52;
  479.     } else {
  480.         pch[c] = '#' + c-62;
  481.     }    
  482.     }  
  483.  
  484.     if (img->palette==lispnil) {
  485.     for (c=0; c<numcols; c++) {
  486.         fprintf(fp, "\"%c\tc #%4.4x%4.4x%4.4x\",\n", pch[c], 
  487.             img->rawpalette[4*c+1], img->rawpalette[4*c+2],
  488.             img->rawpalette[4*c+3]);
  489.         idx[img->rawpalette[4*c]] = c;
  490.     }
  491.     } else {
  492.     c = 0;
  493.     for (palette=img->palette; palette != lispnil; palette = cdr(palette)) {
  494.         color = car(palette);
  495.         fprintf(fp, "\"%c\tc #%4.4x%4.4x%4.4x\",\n", pch[c], 
  496.             c_number(car(cdr(color))),
  497.             c_number(car(cdr(cdr(color)))),
  498.             c_number(car(cdr(cdr(cdr(color)))))
  499.             );
  500.         idx[c_number(car(color))] = c;
  501.         c++;
  502.     }
  503.     }
  504.   
  505.     if (numcols > 74) {
  506.     fprintf(stderr, "write_xpm_file not implemented for %d colors\n",
  507.         numcols);
  508.     return;
  509.     }
  510.  
  511.     rmask = (1 << img->pixelsize) - 1;
  512.     rp = img->rawcolrdata;
  513.     for (r = 0; r < img->h; r++) {
  514.     ri = 8 - img->pixelsize;
  515.     fputc('"', fp);
  516.     for (c = 0; c < img->w; c++) {
  517.         rc = ((int) (*rp >> ri)) & rmask;
  518.         if (ri) {
  519.         ri -= img->pixelsize;
  520.         } else {
  521.         ri = 8 - img->pixelsize;
  522.         rp++;
  523.         }
  524.         fputc(pch[idx[rc]], fp);
  525.     }
  526.     if (r == img->h - 1) {
  527.         fprintf(fp, "\"};\n");
  528.     } else {
  529.         fprintf(fp, "\",\n");
  530.     }
  531.     if ((img->pixelsize * img->w) % 8) {
  532.         rp++;
  533.     }
  534.     }
  535. }
  536.  
  537. /* Given a raw filename, come up with a image family name. */
  538.  
  539. char *
  540. find_imf_name(rawname)
  541. char *rawname;
  542. {
  543.     int lastpos;
  544.     char *a, *b;
  545.  
  546.     b = copy_string(rawname);
  547.     lastpos = strlen(b) - 1;
  548.  
  549.     /* Remove leading path. */
  550.     for (a = b + lastpos - 1; a > b; --a) {
  551.     if (*a == '/') {
  552.         b = a + 1;
  553.         break;
  554.     }
  555.     }
  556.  
  557.     /* Remove trailing extension. */
  558.     if ((a = strchr(b, '.'))) {
  559.     *a = '\0';
  560.     }
  561.  
  562.     return b;
  563. }
  564.  
  565. int
  566. read_any_file(filename, hook)
  567. char *filename;
  568. readimf_hook hook;
  569. {
  570.     ImageFamily *imf;
  571.     char *ext;
  572.     int rc;
  573.  
  574.     /* find extension */
  575.     for (ext = filename + strlen(filename) - 1; ext > filename; ext--) {
  576.     if (*ext == '.') {
  577.         ext++;
  578.         break;
  579.     }
  580.     }
  581.     if (ext == filename)
  582.       ext = "";
  583.  
  584. #ifdef HAVE_XPM
  585.     if (!strcmp(ext, "xpm")) {
  586.     /* try a XPM file */
  587.     imf = get_imf(find_imf_name(filename));
  588.     if (!imf)
  589.       return 0;
  590.     rc = !!read_xpm_file(filename, imf, hook);
  591.     if (hook && rc)
  592.       hook(imf,0);
  593.     return rc;
  594.     }
  595. #endif /* HAVE_XPM */
  596.     if (!strcmp(ext,"b") || !strcmp(ext,"m")) {
  597.     /* try a XBM file */
  598.     imf = get_imf(find_imf_name(filename));
  599.     if (!imf)
  600.       return 0;
  601.     rc = !!read_xbm_file(filename, imf, hook);
  602.     if (hook && rc)
  603.       hook(imf,0);
  604.     return rc;
  605.     } else if (strcmp(ext, "imf") == 0) {
  606.     return load_imf_file(filename, hook);
  607.     }
  608.     return 0;
  609. }
  610.  
  611. void 
  612. reverse_rawdata(imf)
  613. ImageFamily *imf;
  614. {
  615.     int numbytes;
  616.     Image *img;
  617.  
  618.     if (imf == NULL)
  619.       return;
  620.     for (img = imf->images; img; img = img->next) {
  621.     numbytes = img->h * ((img->w + 7) / 8);
  622.     if (img->rawmonodata)
  623.       reverse_bit_endianness(img->rawmonodata, numbytes);
  624.     if (img->rawmaskdata)
  625.       reverse_bit_endianness(img->rawmaskdata, numbytes);
  626.     }
  627. }
  628.